package rpc.utils;

import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpRequest;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*********
 *
 *
 *@author 197
 *@date 2020/6/20 21:33
 *
 **/


public class IpUtils {

  static Logger log = LoggerFactory.getLogger(IpUtils.class);
  static ArrayList<String> localIps = new ArrayList<>();
  static ArrayList<String> netIps = new ArrayList<>();

  static {
    loadIps();
  }

  public IpUtils() {
  }

  static void loadIps() {
    try {
      Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();

      while (netInterfaces.hasMoreElements()) {
        Enumeration<java.net.InetAddress> address = ((NetworkInterface) netInterfaces.nextElement())
            .getInetAddresses();

        while (address.hasMoreElements()) {
          InetAddress ip = (InetAddress) address.nextElement();
          if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && !ip.getHostAddress()
              .contains(":")) {
            netIps.add(ip.getHostAddress());
          } else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && !ip.getHostAddress()
              .contains(":")) {
            localIps.add(ip.getHostAddress());
          }
        }
      }
    } catch (Exception e) {
      log.error("loadIps:{} {}", e.getMessage(), e);
    }

  }

  public static String localIp() {
    String envhost = System.getenv("RPC_HOST");
    if (StringUtils.isNotBlank(envhost)) {
      try {
        InetAddress addr = InetAddress.getByName(envhost);
        String s = addr.getHostAddress();
        return s;
      } catch (Exception var3) {
        log.error("cannot get host address, use local ip");
      }
    }

    envhost = "172.17.0.1";
    localIps.remove(envhost);
    String ip0 = localIp0();
    if (localIps.size() > 0) {
      return localIps.contains(ip0) ? ip0 : (String) localIps.get(0);
    } else if (netIps.size() > 0) {
      return netIps.contains(ip0) ? ip0 : (String) netIps.get(0);
    } else {
      return ip0;
    }
  }

  private static String localIp0() {
    try {
      InetAddress addr = InetAddress.getLocalHost();
      return addr.getHostAddress();
    } catch (Exception var1) {
      return "127.0.0.1";
    }
  }

  public static String getRemoteIP(FullHttpRequest httpRequest, Channel channel) {
    String ip = "";
    try {
      String ipForwarded = httpRequest.headers().get("x-forwarded-for");
      if (StringUtils.isBlank(ipForwarded) || "unknown".equalsIgnoreCase(ipForwarded)) {
        InetSocketAddress insocket = (InetSocketAddress) channel.remoteAddress();
        ip = insocket.getAddress().getHostAddress();
      } else {
        ip = ipForwarded;
      }
    } catch (Exception e) {
      log.error("getRemoteIP(): get remote ip fail!", e);
    }
    if ("0:0:0:0:0:0:0:1".equals(ip)) {
      ip = "127.0.0.1";
    }
    return ip;
  }
}
